#include "resizablerectitem.h"
#include <QPen>
#include <QBrush>
#include <QCursor>

ResizableRectItem::ResizableRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
    : QGraphicsRectItem(x, y, w, h, parent),
      m_resizable(true),
      m_resizing(false),
      m_currentHandle(NoHandle)
{
    setFlags(QGraphicsItem::ItemIsSelectable);//  | QGraphicsItem::ItemIsMovable
    setAcceptHoverEvents(true);
}

void ResizableRectItem::setResizable(bool resizable)
{
    m_resizable = resizable;
    update(); // 样式变化后更新绘制
}

bool ResizableRectItem::isResizable() const
{
    return m_resizable;
}

void ResizableRectItem::setSolidBorderColor(QColor color)
{
    m_solidBorderColor = color;
}

void ResizableRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_resizable && getHandleAtPosition(event->pos()) != NoHandle) {
        m_resizing = true;
        m_currentHandle = getHandleAtPosition(event->pos());
        m_originalPos = event->scenePos();
        m_originalRect = rect();
    } else {
        QGraphicsRectItem::mousePressEvent(event);
    }
}

void ResizableRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_resizing && m_currentHandle != NoHandle) {
        QPointF delta = event->scenePos() - m_originalPos;
        qreal newX = m_originalRect.x();
        qreal newY = m_originalRect.y();
        qreal newW = m_originalRect.width();
        qreal newH = m_originalRect.height();
        const qreal minSize = 5.0; // 最小宽高

        switch (m_currentHandle) {
        case TopLeft:
        {
            // 计算新位置和尺寸（左上角拖动）
            qreal proposedX = newX + delta.x();
            qreal proposedY = newY + delta.y();
            qreal proposedW = newW - delta.x();
            qreal proposedH = newH - delta.y();

            // 当宽度接近最小值时，锁定右边界，只调整左边界
            if (proposedW < minSize) {
                proposedW = minSize;
                proposedX = newX + (newW - proposedW); // 保持右边界不变
            }
            // 当高度接近最小值时，锁定下边界，只调整上边界
            if (proposedH < minSize) {
                proposedH = minSize;
                proposedY = newY + (newH - proposedH); // 保持下边界不变
            }

            newX = proposedX;
            newY = proposedY;
            newW = proposedW;
            newH = proposedH;
            break;
        }
        case BottomRight:
        {
            // 右下角拖动
            newW += delta.x();
            newH += delta.y();

            // 宽度不小于最小值，否则保持当前宽度（左边界不动）
            newW = qMax(newW, minSize);
            // 高度不小于最小值，否则保持当前高度（上边界不动）
            newH = qMax(newH, minSize);
            break;
        }
        case TopRight:
        {
            // 右上角拖动
            qreal proposedRightW = newW + delta.x();
            qreal proposedRightH = newH - delta.y();
            qreal proposedRightY = newY + delta.y();

            // 宽度临界值处理（锁定左边界）
            if (proposedRightW < minSize) {
                proposedRightW = minSize;
            }
            // 高度临界值处理（锁定下边界）
            if (proposedRightH < minSize) {
                proposedRightH = minSize;
                proposedRightY = newY + (newH - proposedRightH);
            }

            newW = proposedRightW;
            newY = proposedRightY;
            newH = proposedRightH;
            break;
        }
        case BottomLeft:
        {
            // 左下角拖动
            qreal proposedLeftX = newX + delta.x();
            qreal proposedLeftW = newW - delta.x();
            qreal proposedLeftH = newH + delta.y();

            // 宽度临界值处理（锁定右边界）
            if (proposedLeftW < minSize) {
                proposedLeftW = minSize;
                proposedLeftX = newX + (newW - proposedLeftW);
            }
            // 高度临界值处理（锁定上边界）
            if (proposedLeftH < minSize) {
                proposedLeftH = minSize;
            }

            newX = proposedLeftX;
            newW = proposedLeftW;
            newH = proposedLeftH;
            break;
        }
        case Left:
        {
            // 左边界拖动
            qreal proposedLeftEdgeX = newX + delta.x();
            qreal proposedLeftEdgeW = newW - delta.x();

            if (proposedLeftEdgeW < minSize) {
                proposedLeftEdgeW = minSize;
                proposedLeftEdgeX = newX + (newW - proposedLeftEdgeW); // 锁定右边界
            }

            newX = proposedLeftEdgeX;
            newW = proposedLeftEdgeW;
            break;
        }
        case Right:
        {
            // 右边界拖动（直接限制最小宽度，左边界不动）
            newW += delta.x();
            newW = qMax(newW, minSize);
            break;
        }


        case Top:
        {
            // 上边界拖动
            qreal proposedTopY = newY + delta.y();
            qreal proposedTopH = newH - delta.y();

            if (proposedTopH < minSize) {
                proposedTopH = minSize;
                proposedTopY = newY + (newH - proposedTopH); // 锁定下边界
            }

            newY = proposedTopY;
            newH = proposedTopH;
            break;
        }
        case Bottom:
        {
            // 下边界拖动（直接限制最小高度，上边界不动）
            newH += delta.y();
            newH = qMax(newH, minSize);
            break;

        }

        default:
            break;
        }

        // 最终确保尺寸不小于最小值（双重保险）
        newW = qMax(newW, minSize);
        newH = qMax(newH, minSize);
        setRect(newX, newY, newW, newH);
    } else {
        QGraphicsRectItem::mouseMoveEvent(event);
    }
}


void ResizableRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    m_resizing = false;
    m_currentHandle = NoHandle;
    QGraphicsRectItem::mouseReleaseEvent(event);
}

void ResizableRectItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    if (m_resizable) {
        ResizeHandle handle = getHandleAtPosition(event->pos());
        updateCursor(handle);
    }
    QGraphicsRectItem::hoverMoveEvent(event);
}

QVariant ResizableRectItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == QGraphicsItem::ItemSelectedHasChanged) {
        update(); // 选中状态变化后更新绘制
    }
    return QGraphicsRectItem::itemChange(change, value);
}

ResizeHandle ResizableRectItem::getHandleAtPosition(const QPointF &pos)
{
    if (!m_resizable || !isSelected()) return NoHandle;

    QRectF rect = this->rect();
    qreal halfHandle = m_handleSize / 2;

    // 检查顶点
    if (QRectF(rect.x() - halfHandle, rect.y() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return TopLeft;
    if (QRectF(rect.right() - halfHandle, rect.y() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return TopRight;
    if (QRectF(rect.x() - halfHandle, rect.bottom() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return BottomLeft;
    if (QRectF(rect.right() - halfHandle, rect.bottom() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return BottomRight;

    // 检查边中点
    if (QRectF(rect.x() - halfHandle, rect.center().y() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return Left;
    if (QRectF(rect.right() - halfHandle, rect.center().y() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return Right;
    if (QRectF(rect.center().x() - halfHandle, rect.y() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return Top;
    if (QRectF(rect.center().x() - halfHandle, rect.bottom() - halfHandle, m_handleSize, m_handleSize).contains(pos))
        return Bottom;

    return NoHandle;
}

QRectF ResizableRectItem::getHandleRect(ResizeHandle handle)
{
    QRectF rect = this->rect();
    qreal halfHandle = m_handleSize / 2;

    switch (handle) {
    case TopLeft:     return QRectF(rect.x() - halfHandle, rect.y() - halfHandle, m_handleSize, m_handleSize);
    case TopRight:    return QRectF(rect.right() - halfHandle, rect.y() - halfHandle, m_handleSize, m_handleSize);
    case BottomLeft:  return QRectF(rect.x() - halfHandle, rect.bottom() - halfHandle, m_handleSize, m_handleSize);
    case BottomRight: return QRectF(rect.right() - halfHandle, rect.bottom() - halfHandle, m_handleSize, m_handleSize);
    case Left:        return QRectF(rect.x() - halfHandle, rect.center().y() - halfHandle, m_handleSize, m_handleSize);
    case Right:       return QRectF(rect.right() - halfHandle, rect.center().y() - halfHandle, m_handleSize, m_handleSize);
    case Top:         return QRectF(rect.center().x() - halfHandle, rect.y() - halfHandle, m_handleSize, m_handleSize);
    case Bottom:      return QRectF(rect.center().x() - halfHandle, rect.bottom() - halfHandle, m_handleSize, m_handleSize);
    default:          return QRectF();
    }
}

void ResizableRectItem::updateCursor(ResizeHandle handle)
{
    switch (handle) {
    case TopLeft:
    case BottomRight:
        setCursor(Qt::SizeFDiagCursor);
        break;
    case TopRight:
    case BottomLeft:
        setCursor(Qt::SizeBDiagCursor);
        break;
    case Left:
    case Right:
        setCursor(Qt::SizeHorCursor);
        break;
    case Top:
    case Bottom:
        setCursor(Qt::SizeVerCursor);
        break;
    default:
        setCursor(Qt::ArrowCursor);
        break;
    }
}

QRectF ResizableRectItem::boundingRect() const
{
    // 扩大边界以包含控制点
    qreal adjust = m_handleSize / 2 + 1;
    return rect().adjusted(-adjust, -adjust, adjust, adjust);
}

void ResizableRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    // 1. 绘制基础实线边框
    QPen solidPen(m_solidBorderColor);
    solidPen.setStyle(Qt::SolidLine);
    solidPen.setWidth(2);
    painter->setPen(solidPen);
    painter->drawRect(rect());

    // 2. 如果选中，在实线上面绘制高亮虚线
    if (isSelected()) {
        QPen dashPen(Qt::white);
        dashPen.setStyle(Qt::DashLine);
        dashPen.setWidth(1);
        painter->setPen(dashPen);
        painter->drawRect(rect());

        // 绘制中间十字线
        // 十字线长10像素
        // 横线的起始坐标点
        int pix = 20;
        int rectWidth = rect().width();
        int rectHeight = rect().height();
        if(rectWidth >= pix && rectHeight >= pix){
            int hengX = rect().x() + (rect().width() - pix) / 2;
            int hengY = rect().y() + rect().height() / 2;

            int zongX = rect().x() + rect().width() / 2;
            int zongY = rect().y() + (rect().height() - pix) / 2;

            // 绘制十字
            dashPen.setColor(m_dashBorderColor);
            dashPen.setStyle(Qt::SolidLine);
            dashPen.setWidth(2);
            painter->setPen(dashPen);
            // 绘制实线十字
            painter->drawLine(hengX,hengY,hengX+pix,hengY);
            painter->drawLine(zongX,zongY,zongX,zongY+pix);

            // 绘制虚线十字
            dashPen.setColor(Qt::white);
            dashPen.setStyle(Qt::DashLine);
            dashPen.setWidth(1);
            painter->setPen(dashPen);

            painter->drawLine(hengX,hengY,hengX+pix,hengY);
            painter->drawLine(zongX,zongY,zongX,zongY+pix);
        }
    }

    // 3. 仅在可调整且选中时绘制控制点
    if (m_resizable && isSelected()) {
        painter->setBrush(QBrush(m_handleColor));
        painter->setPen(Qt::NoPen);

        // 绘制8个控制点（4个顶点 + 4个边中点）
        painter->drawRect(getHandleRect(TopLeft));
        painter->drawRect(getHandleRect(TopRight));
        painter->drawRect(getHandleRect(BottomLeft));
        painter->drawRect(getHandleRect(BottomRight));
        painter->drawRect(getHandleRect(Left));
        painter->drawRect(getHandleRect(Right));
        painter->drawRect(getHandleRect(Top));
        painter->drawRect(getHandleRect(Bottom));
    }
}
